package cn.turboinfo.dongying.api.provider.common.service.impl.user;

import cn.turboinfo.dongying.api.domain.common.service.user.UserLoginService;
import cn.turboinfo.dongying.api.entity.common.enumeration.user.LoginCheckType;
import cn.turboinfo.dongying.api.entity.common.enumeration.user.LoginNameType;
import cn.turboinfo.dongying.api.entity.common.exception.user.UserLoginException;
import cn.turboinfo.dongying.api.entity.common.pojo.user.UserLogin;
import cn.turboinfo.dongying.api.entity.common.pojo.user.UserLoginCreator;
import cn.turboinfo.dongying.api.entity.common.pojo.user.UserLoginUpdater;
import cn.turboinfo.dongying.api.provider.common.repository.database.user.UserLoginDAO;
import cn.turboinfo.dongying.api.provider.common.repository.database.user.UserLoginPO;
import lombok.RequiredArgsConstructor;
import net.sunshow.toolkit.core.qbean.api.request.QPage;
import net.sunshow.toolkit.core.qbean.api.request.QRequest;
import net.sunshow.toolkit.core.qbean.api.response.QResponse;
import net.sunshow.toolkit.core.qbean.helper.component.request.QBeanUpdaterHelper;
import net.sunshow.toolkit.core.qbean.helper.service.impl.DefaultQServiceImpl;
import nxcloud.foundation.core.data.support.annotation.EnableSoftDelete;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;

@RequiredArgsConstructor
@Service
@EnableSoftDelete
public class UserLoginServiceImpl extends DefaultQServiceImpl<UserLogin, Long, UserLoginPO, UserLoginDAO> implements UserLoginService {

    @Override
    public Optional<UserLogin> getByLoginNameAndLoginNameTypeAndLoginCheckTypeAndLoginCheckId(String loginName, LoginNameType loginNameType, LoginCheckType loginCheckType, Long loginCheckId) {
        return dao.getByLoginNameAndLoginNameTypeAndLoginCheckTypeAndLoginCheckId(loginName, loginNameType, loginCheckType, loginCheckId).map(this::convertQBean);
    }

    @Override
    public UserLogin getByLoginNameAndLoginNameTypeAndLoginCheckTypeAndLoginCheckIdEnsure(String loginName, LoginNameType loginNameType, LoginCheckType loginCheckType, Long loginCheckId) {
        return getByLoginNameAndLoginNameTypeAndLoginCheckTypeAndLoginCheckId(loginName, loginNameType, loginCheckType, loginCheckId).orElseThrow(this.getExceptionSupplier("未找到数据, loginName=" + loginName, null));
    }

    @Override
    @Transactional
    public boolean saveIfAbsent(UserLoginCreator creator) throws UserLoginException {
        if (getByLoginNameAndLoginNameTypeAndLoginCheckTypeAndLoginCheckId(creator.getLoginName(), creator.getLoginNameType(), creator.getLoginCheckType(), creator.getLoginCheckId()).isPresent()) {
            return false;
        }
        save(creator);
        return true;
    }

    @Override
    @Transactional
    public UserLogin update(UserLoginUpdater updater) throws UserLoginException {
        UserLoginPO userLoginPO = getEntityWithNullCheckForUpdate(updater.getUpdateId(), dao);

        QBeanUpdaterHelper.copyUpdaterField(userLoginPO, updater);

        return convertQBean(userLoginPO);
    }

    @Override
    public QResponse<UserLogin> findAll(QRequest request, QPage requestPage) {
        return convertQResponse(findAllInternal(request, requestPage));
    }

    @Override
    public List<UserLogin> findByUserId(Long userId) {
        return convertStreamQBeanToList(dao.findByUserId(userId).stream());
    }

    private Page<UserLoginPO> findAllInternal(QRequest request, QPage requestPage) {
        return dao.findAll(convertSpecification(request), convertPageable(requestPage));
    }

    @Override
    public List<UserLogin> findByLoginNameAndLoginNameType(String loginName, LoginNameType loginNameType) {
        return convertStreamQBeanToList(dao.findByLoginNameAndLoginNameType(loginName, loginNameType).stream());
    }

    @Override
    public List<UserLogin> findByLoginNameAndLoginNameTypeAndLoginCheckType(String loginName, LoginNameType loginNameType, LoginCheckType loginCheckType) {
        return convertStreamQBeanToList(dao.findByLoginNameAndLoginNameTypeAndLoginCheckType(loginName, loginNameType, loginCheckType).stream());
    }

    @Override
    protected Supplier<? extends RuntimeException> getExceptionSupplier(String message,
                                                                        Throwable cause) {
        return () -> new UserLoginException(message, cause);
    }
}
